package com.otod.pm.prj.service;


import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.otod.base.exception.AppException;
import com.otod.base.service.BaseService;
import com.otod.commons.utils.Collections3;
import com.otod.commons.utils.DateUtils;
import com.otod.pm.constants.PmConstant;
import com.otod.pm.prj.bo.StepBo;
import com.otod.pm.prj.mapper.StepMapper;
import com.otod.pm.prj.mapper.TaskMapper;
import com.otod.pm.prj.vo.ProjectVo;
import com.otod.pm.prj.vo.StepTpVo;
import com.otod.pm.prj.vo.StepVo;
import com.otod.pm.prj.vo.TaskVo;


/**
 * 阶段管理
 * @author yiChen
 */
@Service
@Transactional(readOnly=true)
public class StepService extends BaseService {
	
	@Autowired
	StepMapper stepMapper;
	@Autowired
	TaskMapper taskMapper;
	
	@Autowired
	
	TaskService taskService;

	@Autowired 
	StepTpService stepTpService;
	
	@Autowired
	private ProjectService projectService;
	
	/**
	 * 设置新增阶段时的阶段开始时间与状态
	 * 
	 */
	public StepVo setStartDate(StepVo stepVo){
		
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("prjId", stepVo.getPrjId());
		List<StepVo> stepVoList = stepMapper.queryForList(map);
		ProjectVo projectVo = projectService.getById(stepVo.getPrjId());
		Integer sort = 0;
		StepVo vo = null;
		
		if(stepVoList.size()==0){
			stepVo.setStartDate(projectVo.getStartDate());
			if(DateUtils.getDaysBetweenTwoDates(DateUtils.formatDate(projectVo.getStartDate(),"yyyyMMdd"),DateUtils.getDate("yyyyMMdd"))<0){
				stepVo.setStatus(PmConstant.STEP_STATUS_READY);
			}else{
				if(PmConstant.PRJ_STATUS_STARTING.equals(projectVo.getStatus())){
					
					stepVo.setStatus(PmConstant.STEP_STATUS_STARTING);
				}else{
					
					stepVo.setStatus(PmConstant.STEP_STATUS_READY);
				}
			}
			stepVo.setSort(sort+1);
		}else{
			for (StepVo stepVo2 : stepVoList) {
				if(stepVo2.getSort()>sort){
					sort = stepVo2.getSort();
					vo = stepVo2;
				}else{
					continue;
				}
			}
			
			stepVo.setStartDate(vo.getEndDate());
			//前面的日期大于后面的日期 则返回负数
			if(DateUtils.getDaysBetweenTwoDates(DateUtils.formatDate(vo.getEndDate(),"yyyyMMdd"),DateUtils.getDate("yyyyMMdd"))<0){
				stepVo.setStatus(PmConstant.STEP_STATUS_READY);
			}else{
				
				if(PmConstant.PRJ_STATUS_STARTING.equals(projectVo.getStatus())){
					
					stepVo.setStatus(PmConstant.STEP_STATUS_STARTING);
				}else{
					
					stepVo.setStatus(PmConstant.STEP_STATUS_READY);
				}
			}
			stepVo.setSort(sort+1);
		}
		return stepVo;
	}
	/**
	 * 设置新增阶段时的阶段开始时间与状态and阶段排序
	 * @throws AppException 
	 * 
	 */
	@Transactional
	public StepVo setStartDateAndSort(StepVo stepVo) throws AppException{
		//插入阶段操作的必要条件是插入序号必须大于等于二
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("prjId", stepVo.getPrjId());
		List<StepVo> stepVoList = stepMapper.queryForList(map);
		//ProjectVo projectVo = projectService.getById(stepVo.getPrjId());
		StepVo vo = new StepVo();
		Integer days = DateUtils.getDaysBetweenTwoDates(DateUtils.formatDate(stepVo.getStartDate(),"yyyyMMdd"), DateUtils.formatDate(stepVo.getEndDate(),"yyyyMMdd"));
		List<StepVo> changeStepList = new ArrayList<StepVo>();
		
			for (StepVo stepVo2 : stepVoList) {
				if(stepVo2.getSort()>=stepVo.getSort()){
					changeStepList.add(stepVo2);//加入list为后续工作做准备
						//时间后移，sort+1 阶段下得任务时间后移  后续阶段重复此操作
				}
				if(stepVo2.getSort()==(stepVo.getSort()-1)){
					vo = stepVo2;//原来位置的阶段 
					
				}
				
			}
			if(vo.getStatus() == PmConstant.STEP_STATUS_FLISH){
				//不是完成状态的阶段 之后才能添加（上一阶段的状态必须是进行中或者是准备中才能添加）
				throw new AppException("不能在该位置插入阶段，请重新设置阶段位置！");
			}else{
				stepVo.setStatus(PmConstant.STEP_STATUS_READY);//设置阶段状态为准备
				for (StepVo stepVo2 : changeStepList) {
					Map<String,Object> updateMap = new HashMap<String,Object>();
					updateMap.put("sort", stepVo2.getSort()+1);
					updateMap.put("startDate", DateUtils.addDays(stepVo2.getStartDate(), days));
					updateMap.put("endDate", DateUtils.addDays(stepVo2.getEndDate(), days));
					updateMap.put("uuid", stepVo2.getUuid());
					//stepVo2.setSort(stepVo2.getSort()+1);
					//stepVo2.setStartDate(DateUtils.addDays(stepVo2.getStartDate(), days));
					//stepVo2.setEndDate(DateUtils.addDays(stepVo2.getEndDate(), days));
					//阶段下得任务设置 时间后移
					this.update(updateMap);
					List<TaskVo> taskList = taskService.queryValidList(stepVo2.getUuid());
					for (TaskVo taskVo : taskList) {
						updateMap.clear();
						updateMap.put("uuid", taskVo.getUuid());
						updateMap.put("startDate", DateUtils.addDays(taskVo.getStartDate(), days));
						updateMap.put("endDate", DateUtils.addDays(taskVo.getEndDate(), days));
						//taskVo.setStartDate(DateUtils.addDays(taskVo.getStartDate(), days));
						//taskVo.setEndDate(DateUtils.addDays(taskVo.getEndDate(), days));
						taskService.update(updateMap);
					}
				}
			}
			
		
		return stepVo;
	}
	
	
	/**
	 * 新增阶段
	 * @param stepVo
	 * @throws AppException 
	 */
	@Transactional
	public StepVo insert(StepVo stepVo) throws AppException {
		stepVo.setUuid(super.getUUID());
		if(stepVo.getSort()!=null&&stepVo.getSort()!=0){
			stepVo = setStartDateAndSort(stepVo);
		}else{
			stepVo = setStartDate(stepVo);
		}
		stepMapper.insert(stepVo);
		return stepVo;
	}
	
	/**
	 * 修改
	 * @param map
	 */
	@Transactional
	public void update(Map<String, Object> map){
		stepMapper.update(map);
	}
	
	/**
	 * 删除
	 * @param id
	 */
	@Transactional
	public void deleteById(String id){
		StepVo stepVo = this.getById(id);
		Integer sort = stepVo.getSort();
		//将删除阶段的后续阶段序号提前
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("prjId", stepVo.getPrjId());
		List<StepVo> stepList =  stepMapper.queryForList(params);
		if(Collections3.isNotEmpty(stepList)){
			for (StepVo stepVo2 : stepList) {
				if(stepVo2.getSort()>sort){
					Map<String,Object> map = new HashMap<String,Object>();
					map.put("uuid", stepVo2.getUuid());
					map.put("sort", stepVo2.getSort()-1);
					this.update(map);
				}
			}
			
		}
		
		stepMapper.deleteById(id);
		taskMapper.deleteByStepId(id);
	}
	
	/**
	 * 主键查询
	 * @param id
	 */
	public StepVo getById(String id){
		return stepMapper.getById(id);
	}
	
	/**
	 * 查询产品下所有有效果的阶段
	 * @param prjId 项目ID
	 */
	public List<StepVo> queryStepVoList(String prjId){
		Map<String,Object> param = new HashMap<String, Object>();
		param.put("prjId",prjId);
		return stepMapper.queryForList(param);
	}
	
	/**
	 * 查询产品下所有有效果的阶段
	 * @param prjId 项目ID
	 */
	public List<StepBo> queryStepList(String prjId,String empNo){
		List<StepVo> list = this.queryStepVoList(prjId);
		List<StepBo> listStepBo = new ArrayList<StepBo>();
		StepBo bo;
		for (StepVo stepVo : list) {
			bo = new StepBo();
			BeanUtils.copyProperties(stepVo, bo);
			bo.setTaskList(taskService.queryValidList(stepVo.getUuid()));
			listStepBo.add(bo);
		}
		return listStepBo;
	}
	
	/**
	 * 通过模板生成项目阶段
	 * @param prjId
	 * @param stepId
	 * @param tpId
	 * @throws AppException
	 * 
	 * @author longjiwnei
	 */
	@Transactional
	public void createPrjStepByTemplate(String prjId,String tpId,TaskVo vo)throws AppException {
		//通过tpId查询数据
	
		
		List<StepTpVo> list = Lists.newArrayList();
		list = stepTpService.queryValidList(tpId);
		if(list.isEmpty()){
			throw new AppException("模板未配置阶段");
		}
		StepVo stepVo;
		//通过项目的id删除 prj_id
		
		taskMapper.deleteByPrjId(prjId);
		stepMapper.deletePrjId(prjId);
		for (StepTpVo stepTpVo : list) {
			stepVo = new StepVo();
			//从另外一张表赋值数据
			BeanUtils.copyProperties(stepTpVo,stepVo);
			stepVo.setPrjId(prjId);
			
			stepVo = this.insert(stepVo);
			//得到stepId
			taskService.createPrjTaskByTemplate(prjId, stepTpVo.getUuid(),stepVo.getUuid(), tpId,vo);
		}
		
	}
	/**
	 * 设置阶段状态
	 * @param vo staus
	 * return stepVo
	 */
	@Transactional
	public void changeStepStatus(String stepId,String status){
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("uuid", stepId);
		map.put("status", status);
		map.put("startDate", DateUtils.getCurrentDate());
		this.update(map);
	}
	
	/**
	 * 设置阶段完成,下一个阶段设置开始
	 * @param uuid
	 */
	@Transactional
	public void updateStatusCpt(String stepId){
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("uuid", stepId);
		map.put("status", PmConstant.STEP_STATUS_FLISH);
		map.put("endDate", DateUtils.getCurrentDate());
		this.update(map);
		StepVo stepVo = this.getById(stepId);
		Integer sort = stepVo.getSort()+1;
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("sort", sort);
		params.put("prjId", stepVo.getPrjId());
		List<StepVo> stepList =  stepMapper.queryForList(params);
		if(Collections3.isNotEmpty(stepList)){
			String nextStepId = stepList.get(0).getUuid();
			//启动下一阶段
			this.changeStepStatus(nextStepId, PmConstant.STEP_STATUS_STARTING);
			//下一阶段任务开始设置
			this.changeStatusStart(nextStepId); 
		}else if(stepList.size() == 0){
			//已经是最后一个阶段项目结项
			projectService.changePrjStatus(stepVo.getPrjId(), PmConstant.PRJ_STATUS_FLISH);
		}
	}
	
	/**
	 * 设置该开始阶段下的任务状态
	 * @param vo staus
	 * return stepVo
	 */
	@Transactional
	public void changeStatusStart(String stepId){
		//设置该阶段下的任务状态
			List<TaskVo> taskList = taskService.queryValidList(stepId);
			Map<String,Object> map = new HashMap<String,Object>();
			Date date = DateUtils.getCurrentDate();
			for (TaskVo taskVo : taskList) {
				if(DateUtils.getDaysBetweenTwoDates(DateUtils.formatDate(taskVo.getStartDate(),"yyyyMMdd"), DateUtils.formatDate(date,"yyyyMMdd"))<0){
					map.put("uuid", taskVo.getUuid());
					map.put("status", PmConstant.TASK_STATUS_STARTING);
					map.put("startDate",date );
					taskService.update(map);
				}
			}
	}
	
	/**
	 * 判断当前阶段的任务是否已完成
	 * @param uuid
	 * return 
	 */
	@Transactional
	public Integer isStepTaskCmt(String stepId){
		List<TaskVo> taskList = taskService.queryValidList(stepId);
		//判断当前阶段的任务是否都已完成
		for (TaskVo taskVo : taskList) {
			if(PmConstant.TASK_STATUS_READY.equals(taskVo.getStatus())){
				return 0;//有未开始任务，禁止跳转
			}
			if(!taskVo.getStatus().equals(PmConstant.TASK_STATUS_FLISH)){
				return 1;//有未完成任务，询问是否强制跳转
			}
		}
		return 2;//都已完成可以跳转
	}
	/**
	 * 
	 * @param prjId
	 * @return
	 */
	public List<StepVo> selectStep(String prjId){
		List<StepVo> list = new ArrayList<StepVo>();
		Map<String, Object> map = new HashMap<String,Object>();
		map.put("prjId", prjId);
		list = stepMapper.queryForList(map);
		return list;
	}
	
	/**
	 * 逻辑删除 阶段信息
	 * @param map
	 */
	@Transactional
	public void remove(Map<String, Object> map) {
		stepMapper.remove(map);
	}
	
}
